package com.richard.library.basic.util;

import android.graphics.drawable.Drawable;
import android.widget.Toast;

import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;

import com.richard.library.basic.R;
import com.richard.library.basic.simple.SimpleException;
import com.richard.library.context.AppContext;

/**
 * 吐司消息
 */
public final class ToastUtil {

    private static Toasty.Config config;
    private static int defaultBackgroundColor;
    private static int defaultTextColor;


    public static void init() {
        config = Toasty.Config.getInstance();
        config.tintIcon(false)
                //.setToastTypeface(@NonNull Typeface typeface) // optional
                //.setTextSize(int sizeInSp) // optional
                .apply(); // required
    }

    /**
     * 是否图标调色
     */
    public static void setTintIcon(boolean isTintIcon) {
        if (config == null) {
            init();
        }
        config.tintIcon(isTintIcon)
                .apply();
    }

    /**
     * 设置显示位置
     */
    public static void setGravity(int gravity, int xOffset, int yOffset) {
        if (config == null) {
            init();
        }
        config.setGravity(gravity, xOffset, yOffset)
                .apply(); // required
    }

    /**
     * 设置显示位置
     */
    public static void setGravity(int gravity) {
        if (config == null) {
            init();
        }
        config.setGravity(gravity)
                .apply(); // required
    }

    /**
     * 设置文本自提大小
     */
    public static void setTextSize(int textSizeSp) {
        if (config == null) {
            init();
        }
        config.setTextSize(textSizeSp)
                .apply(); // required
    }

    /**
     * 设置背景颜色和文本颜色
     *
     * @param backgroundColor 背景颜色
     * @param textColor       文本颜色
     */
    public static void setColor(@ColorInt int backgroundColor, @ColorInt int textColor) {
        defaultBackgroundColor = backgroundColor;
        defaultTextColor = textColor;
    }

    /**
     * 设置是否允许队列弹出消息提示
     */
    public static void setAllowQueue(boolean allowQueue){
        if (config == null) {
            init();
        }
        config.setAllowQueue(allowQueue)
                .apply(); // required
    }

    /**
     * 显示吐司消息
     */
    private static void show(final String text, int duration) {
        if (UIThread.isMainThread()) {
            if (defaultBackgroundColor != 0 || defaultTextColor != 0) {
                custom(text, null, defaultBackgroundColor, defaultTextColor, duration);
            } else {
                Toasty.normal(AppContext.get(), text == null ? "" : text, duration).show();
            }

            return;
        }

        UIThread.runOnUiThread(() -> {
            if (defaultBackgroundColor != 0 || defaultTextColor != 0) {
                custom(text, null, defaultBackgroundColor, defaultTextColor, duration);
            } else {
                Toasty.normal(AppContext.get(), text == null ? "" : text, duration).show();
            }
        });
    }

    /**
     * 显示短时吐司
     */
    public static void showShort(final String text) {
        show(text, Toast.LENGTH_SHORT);
    }

    /**
     * 显示短时吐司
     */
    public static void showShort(@StringRes int resId) {
        show(AppContext.getString(resId), Toast.LENGTH_SHORT);
    }

    /**
     * 显示短时吐司
     *
     * @param format 字符格式模板
     * @param args   填充参数
     */
    public static void showShort(@NonNull String format, Object... args) {
        show(String.format(format, args), Toast.LENGTH_SHORT);
    }

    /**
     * 显示长时吐司
     */
    public static void showLong(final String text) {
        show(text, Toast.LENGTH_LONG);
    }

    /**
     * 显示长时吐司
     */
    public static void showLong(@StringRes final int resId) {
        show(AppContext.getString(resId), Toast.LENGTH_LONG);
    }

    /**
     * 显示长时吐司
     *
     * @param format 字符格式模板
     * @param args   填充参数
     */
    public static void showLong(@NonNull String format, Object... args) {
        show(String.format(format, args), Toast.LENGTH_LONG);
    }

    /**
     * 显示成功消息吐司
     */
    public static void showSuccess(String text) {
        showSuccess(text, Toast.LENGTH_SHORT);
    }

    /**
     * 显示成功消息吐司
     */
    public static void showLongSuccess(String text) {
        showSuccess(text, Toast.LENGTH_LONG);
    }

    private static void showSuccess(String text, int duration) {
        if (UIThread.isMainThread()) {
            Toasty.success(AppContext.get(), text, duration).show();
        } else {
            UIThread.runOnUiThread(() -> {
                Toasty.success(AppContext.get(), text, duration).show();
            });
        }
    }

    /**
     * 显示错误消息吐司
     */
    public static void showError(String text) {
        showError(text, Toast.LENGTH_SHORT);
    }

    /**
     * 显示错误消息吐司
     */
    public static void showLongError(String text) {
        showError(text, Toast.LENGTH_LONG);
    }

    /**
     * 显示错误消息吐司
     */
    public static void showError(String text, int duration) {
        if (UIThread.isMainThread()) {
            Toasty.error(AppContext.get(), text, duration).show();
        } else {
            UIThread.runOnUiThread(() -> {
                Toasty.error(AppContext.get(), text, duration).show();
            });
        }
    }

    /**
     * 显示警告消息吐司
     */
    public static void showWarning(String text) {
        showWarning(text, Toast.LENGTH_SHORT);
    }

    /**
     * 显示警告消息吐司
     */
    public static void showLongWarning(String text) {
        showWarning(text, Toast.LENGTH_LONG);
    }

    /**
     * 显示警告消息吐司
     */
    public static void showWarning(String text, int duration) {
        if (UIThread.isMainThread()) {
            Toasty.warning(AppContext.get(), text, duration).show();
        } else {
            UIThread.runOnUiThread(() -> {
                Toasty.warning(AppContext.get(), text, duration).show();
            });
        }
    }

    /**
     * 显示错误消息
     *
     * @param throwable  异常信息
     * @param defaultMsg 默认显示文本
     */
    public static void show(Throwable throwable, String defaultMsg) {
        showShort(getErrorText(throwable, defaultMsg));
    }

    /**
     * 显示错误消息
     *
     * @param throwable 异常信息
     */
    public static void show(Throwable throwable) {
        show(throwable, AppContext.getString(R.string.toast_operate_fail));
    }

    /**
     * 自定义显示toast
     *
     * @param text      文本内容
     * @param icon      icon小图标(可为null)
     * @param tintColor 背景颜色值
     * @param textColor 文本颜色值
     */
    public static void custom(String text, Drawable icon, @ColorInt int tintColor, @ColorInt int textColor) {
        custom(text, icon, tintColor, textColor, Toast.LENGTH_SHORT);
    }

    /**
     * 自定义显示toast
     *
     * @param text      文本内容
     * @param iconResId icon小图标
     * @param tintColor 背景颜色值
     * @param textColor 文本颜色值
     */
    public static void custom(String text, @DrawableRes int iconResId, @ColorInt int tintColor, @ColorInt int textColor, int duration) {
        custom(text, AppContext.getDrawable(iconResId), tintColor, textColor, duration);
    }

    /**
     * 自定义显示toast
     *
     * @param text      文本内容
     * @param icon      icon小图标
     * @param tintColor 背景颜色值
     * @param textColor 文本颜色值
     */
    public static void custom(String text, Drawable icon, @ColorInt int tintColor, @ColorInt int textColor, int duration) {
        if (UIThread.isMainThread()) {
            Toasty.custom(AppContext.get(), text, icon, tintColor, textColor, duration, icon != null, false).show();
        } else {
            UIThread.runOnUiThread(() -> {
                Toasty.custom(AppContext.get(), text, icon, tintColor, textColor, duration, icon != null, false).show();
            });
        }
    }

    /**
     * 获取错误消息文本
     *
     * @param throwable  异常信息
     * @param defaultMsg 默认显示文本
     */
    public static String getErrorText(Throwable throwable, String defaultMsg) {
        if (throwable instanceof SimpleException) {
            return throwable.getMessage();
        }
        return defaultMsg;
    }
}